package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"time"
)

func main() {

	// Scanner , Scanner使用了缓存，各个“字段”不能超过缓存长度, Scanner需要一个SplitFunc来确定"字段"之间的分隔符号,默认使用行切分函数，
	//包自带的切分函数还有字节、单词、utf8切分函数，也可以自定义切分函数
	strRd := strings.NewReader("this is a text split by \\n\nthis is line 2\nthis is line 3\nline4 世界在这里\n")
	fmt.Println("1. bufio.Scanner, default is split by line.")
	var s *bufio.Scanner
	s = bufio.NewScanner(strRd)
	fmt.Println("1.*Scanner.Text(): ")
	for s.Scan() {
		fmt.Printf("[%s]\n", s.Text()) //*Scanner.Text() 是值传递, *Scanner.Bytes()是引用传递
		time.Sleep(time.Second / 5)
	}

	// Scanner 以rune分割
	strrd1 := strings.NewReader("this is a text split by \\n\nthis is line 2\nthis is line 3\nline4 世界在这里\n")
	s1 := bufio.NewScanner(strrd1)
	s1.Split(bufio.ScanRunes)
	fmt.Println("1. bufio.Scanner, split by rune.")
	for s1.Scan() {
		fmt.Printf("%s | ", s1.Text())
	}
	fmt.Println("")

	// Scanner 以word分割
	strrd2 := strings.NewReader("this is a text split by \\n\nthis is line 2\nthis is line 3\nline4 世界在这里\n")
	s2 := bufio.NewScanner(strrd2)
	s2.Split(bufio.ScanWords)
	fmt.Println("1. bufio.Scanner, split by word.")
	for s2.Scan() {
		fmt.Printf("%s | ", s2.Text())
	}
	fmt.Printf("\n\n")

	// 2 bufio.Reader.Peek()
	var r *bufio.Reader
	r = bufio.NewReader(os.Stdin) // bufio.NewReader是把io.Reader类型转换成*bufio.Reader类型， 相当于bufio.NewReaderSize(io.Reader,4096)
	var bs []byte
	// func (b *Reader) Peek(n int) ([]byte, error)
	bs, _ = r.Peek(3)
	fmt.Printf("2.bufio.Reader.Peek(3) :%s\n", bs)

	// 2  bufio.Reader.Read()
	bs1 := make([]byte, 5)
	count, err := r.Read(bs1) //func (b *Reader) Read(p []byte) (n int, err error)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("2.bufio.Reader.Read([]byte) [note []byte's cap is 5]: %s |count=%d\n", bs1, count)

	// 2  bufio.Reader.Readbytes()  syntax func (b *Reader) ReadBytes(delim byte) ([]byte, error)
	brd0 := bufio.NewReader(os.Stdin)
	bs2, _ := brd0.ReadBytes('\n')
	fmt.Printf("2 bufio.Reader.ReadBytes('\\n'): %s\n\n", bs2)

	var str1 string
	filep, _ := os.Open("/etc/hosts")
	fbrd := bufio.NewReader(filep)
	for {
		str1, err = fbrd.ReadString('\n')
		if err == io.EOF {
			fmt.Errorf("2.**bufio.Reader.ReadBytes() meet io.EOF, %v\n", err)
			break
		}
		if err != nil {
			fmt.Errorf("/etc/hosts, %v\n", err)
			os.Exit(1)
		}
		fmt.Printf("2 bufio.Reader.ReadString('\\n'): %s", str1)
	}

	//func (b *Reader) WriteTo(w io.Writer) (n int64, err error)
	fmt.Println("\n2 next will show bufio.Reader.WriteTo(), type CTRL+D finish:")
	brd0.WriteTo(os.Stdout)
	fmt.Println("")

	//func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
	srd := strings.NewReader("192.168.1.100")
	brd := bufio.NewReader(srd)

	for {
		bs3, err := brd.ReadSlice('.')
		fmt.Printf("2.bufio.Reader.ReadSlice('.'): %s\n", bs3)
		if err == io.EOF { //读取文件先处理error为EOF的情况，再处理 != nil 的情况
			fmt.Printf("meet io.EOF")
			break
		}
		if err != nil {
			fmt.Errorf("2.bufio.Reader.ReadSlice Failed.%v\n", err)
			os.Exit(1)
		}
	}

}
